package me.zhengjie.modules.weixin.handler;

import com.alibaba.fastjson.JSON;
import me.zhengjie.config.constant.WeChatConstant;
import me.zhengjie.modules.weixin.analyzer.AnalyzerFactory;
import me.zhengjie.modules.weixin.dto.WeChatAccount;
import me.zhengjie.modules.weixin.dto.WeChatMessage;
import me.zhengjie.modules.weixin.dto.WeChatMessageRequest;
import me.zhengjie.modules.weixin.message.AnalyzerAsyncMessage;
import me.zhengjie.modules.weixin.message.AnalyzerReplyMessage;
import me.zhengjie.modules.weixin.message.reply.AbstractReplyMessage;
import me.zhengjie.modules.weixin.processor.ProcessorFactory;
import me.zhengjie.modules.weixin.utils.DateUtil;
import me.zhengjie.utils.AliMessageUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * webapi 核心处理类
 */
@Component
public class HandlerFactory {
    private static final Logger log = LoggerFactory.getLogger(HandlerFactory.class);
    @Autowired
    private AnalyzerFactory analyzer;

    @Autowired
    private ProcessorFactory processor;

    public String handle(WeChatAccount account, Map<String, Object> receiveMsg) throws Exception {

        AbstractReplyMessage replyMessage = doHandle(account, receiveMsg);

        if (null != replyMessage && replyMessage.isValidReply()) {
            return replyMessage.toXML();
        }
        return WeChatConstant.SUCCESS_FLAG;
    }

    private AbstractReplyMessage doHandle(WeChatAccount account, Map<String, Object> receiveMsg) throws Exception {

        String openId = (String) receiveMsg.get("FromUserName");

        // 解析接收到的用户消息
        WeChatMessage weChatMessage = analyzer.analyze(account, receiveMsg);

        AnalyzerReplyMessage hitReply = new AnalyzerReplyMessage();
        hitReply.setModule("");
        hitReply.setRule("");

        AbstractReplyMessage replyMsg = null;
        for (AnalyzerReplyMessage reply : weChatMessage.getReplyMessage()) {
            if (StringUtils.isBlank(reply.getModule())) {
                continue;
            }
            try {
                // 处理需要回复用户的消息
                reply.setReceiveMsg(receiveMsg);
                replyMsg = (AbstractReplyMessage) processor.process(account, reply);
                if (null != replyMsg && replyMsg.isValidReply()) {
                    hitReply = reply;
                    break;
                }
            } catch (Exception e) {
            }
        }

        // 异步发送MQ消息，消费消息记录交互事件和记录需发送的客服消息
        if (CollectionUtils.isNotEmpty(weChatMessage.getAsyncMessage())) {

            WeChatMessageRequest mqRequest = new WeChatMessageRequest();
            mqRequest.setAppId(account.getAppId());
            mqRequest.setMsgType(weChatMessage.getMsgType());
            mqRequest.setReceiveMsg(receiveMsg);

            Date now = new Date();
            String today = DateUtil.date2String(now, "yyyyMMdd");

            for (AnalyzerAsyncMessage async : weChatMessage.getAsyncMessage()) {

                if (StringUtils.isNotBlank(async.getDelayDateTime())) {
                    // 如果配置的是具体的某个时间点，则计算到当前时间的分钟数作为延迟时间
                    Date delayDate = DateUtil.addDay(now, null != async.getAddDays() ? async.getAddDays() : 0);
                    String delayDateStr = DateUtil.date2String(delayDate, "yyyy-MM-dd " + async.getDelayDateTime());
                    delayDate = DateUtil.string2Date(delayDateStr);
                    // 此处的today为消息实际的发送日期
                    today = DateUtil.date2String(delayDate, "yyyyMMdd");
                    async.setDelayTime(delayDate.before(now) ? 0L : DateUtil.getMinutesOf2Date(now, delayDate));
                }
                // 优先使用配置的数据，如若没有配置则使用枚举定义的，方便后续扩展

            }
        }

        Map<String, String> extraInfo = new HashMap<>(4);
        extraInfo.put("hitReply", JSON.toJSONString(hitReply));
        extraInfo.put("replyMsg", JSON.toJSONString(replyMsg));

        return replyMsg;
    }
}
